#include "KDMPrimaryGeneratorAction.hh"
#include "KDMGlobals.hh"
#include "G4Event.hh"
#include "G4PrimaryVertex.hh"
#include <G4PrimaryParticle.hh>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <sstream>
using namespace std;

KDMPrimaryGeneratorAction::KDMPrimaryGeneratorAction(G4String eventFilePath, G4String posFilePath, int neutronCount) {
	numOfNeutrons = neutronCount;
	posList = new double*[numOfNeutrons];
	interface = new G4HEPEvtInterface(eventFilePath);

	ifstream pFile(posFilePath);
	int bufSize = 1024;
	char* buffer = new char[bufSize];
	for (int i = 0; i < numOfNeutrons; i++) {
		posList[i] = new double[3];
		for (int j = 0; j < 3; j++) {
			char delim = '\t';
			if (j == 2)
				delim = '\n';
			pFile.getline(buffer, bufSize, delim);
			posList[i][j] = atof(buffer);
		}
	}
	delete[] buffer;
	pFile.close();
	cout << endl;
}

KDMPrimaryGeneratorAction::~KDMPrimaryGeneratorAction() {
	delete interface;

	for (int i = 0; i < numOfNeutrons; i++)
		delete[] posList[i];
	delete[] posList;
}

void KDMPrimaryGeneratorAction::GeneratePrimaries(G4Event* event) {
	eventNum++;
	interface->SetParticlePosition(G4ThreeVector(posList[eventNum][0], posList[eventNum][1], posList[eventNum][2]));
	interface->SetParticleTime(0);
	interface->GeneratePrimaryVertex(event);
	G4PrimaryParticle* part = event->GetPrimaryVertex()->GetPrimary();
//	double p = pow(pow(part->GetPx(), 2) + pow(part->GetPy(), 2) + pow(part->GetPz(), 2), .5);
	stringstream ss;
	ss.width(15);
	ss.fill('0');
	ss << left << ((double) eventNum) / numOfNeutrons * 100;
	cout << "\r" << ss.str() << " % done" << flush;
}
